﻿using GalaSoft.MvvmLight;
using System.ServiceModel.DomainServices.Client;
using SGTLightAccent.Web.Models;
using SGTLightAccent.Web.Services;
using GalaSoft.MvvmLight.Command;
using SGTLightAccent.Views;
using System;
using GalaSoft.MvvmLight.Messaging;
using SGTLightAccent.Models;
using System.Windows.Printing;
using SGTLightAccent.Plantillas;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;


namespace SGTLightAccent.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class DepositosViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the DepositosViewModel class.
        /// </summary>
        /// 
        private SGTDomainContext contexto;
        private EntitySet<Deposito> _depositos;
        private EntitySet<Carga> _cargas;
        private Deposito _nuevoDeposito;
        private Deposito _depositoSeleccionado;
        private EntitySet<Remito_Barco> _remitos;
        private Remito_Barco _nuevoRemito;
        private Remito_Barco _remitoSeleccionado;
        private EntitySet<Proveedor> _proveeedores;
        private bool _filtroChkBarco;
        private bool _filtroChkProducto;
        private bool _filtroChkFchIni;
        private bool _filtroChkFchFin;
        private DateTime _filtroFechaIni;
        private DateTime _filtroFechaFin;
        private DateTime _fechaAhora;
        private string _filtroBarco;
        private string _filtroProducto;
        
        private Carga _cargaSeleccionada;
        private Carga _cargaFormulario;
        private decimal _pesoNeto;
        private decimal _pesoANP;
        private bool _estaCargando;
        private PagedCollectionView _remitosPaginado;
        
        public RelayCommand BotonGuardarDeposito { get; private set; }
        public RelayCommand BotonNuevoDeposito { get; private set; }
        public RelayCommand BotonModificarDeposito { get; private set; }
        public RelayCommand BotonBuscarDeposito { get; private set; }
        public RelayCommand BotonBuscarCarga { get; private set; }
        public RelayCommand BotonNavegarRemito { get; private set; }
        public RelayCommand BotonNuevoRemito { get; private set; }
        public RelayCommand BotonCargarRemitosCarga { get; private set; }
        public RelayCommand BotonGuardarRemitoCarga { get; private set; }
        public RelayCommand BotonImprimirRemito { get; private set; }
        public RelayCommand BotonModificarRemito { get; private set; }
        public RelayCommand BotonEliminarRemito { get; private set; }



        #region Fields

        public decimal PesoANP
        {
            get { return _pesoANP; }
            set
            {

                _pesoANP = value;
                RaisePropertyChanged("PesoANP");


            }
        }

        public decimal PesoNeto
        {
            get { return _pesoNeto; }
            set
            {

                _pesoNeto = value;
                RaisePropertyChanged("PesoNeto");


            }
        }

        public Remito_Barco RemitoSeleccionado
        {
            get { return _remitoSeleccionado; }
            set
            {

                _remitoSeleccionado = value;
                RaisePropertyChanged("RemitoSeleccionado");


            }
        }

        public Remito_Barco NuevoRemito
        {
            get { return _nuevoRemito; }
            set
            {

                _nuevoRemito = value;
                RaisePropertyChanged("NuevoRemito");


            }
        }

        public Carga CargaSeleccionada
        {
            get { return _cargaSeleccionada; }
            set
            {
                if (value != null)
                {
                    _cargaSeleccionada = value;
                    RaisePropertyChanged("CargaSeleccionada");
                }


            }
        }
        public Carga CargaFormulario
        {
            get { return _cargaFormulario; }
            set
            {

                _cargaFormulario = value;
                RaisePropertyChanged("CargaFormulario");


            }
        }

        public Deposito DepositoSeleccionado
        {
            get { return _depositoSeleccionado; }
            set
            {

                _depositoSeleccionado = value;
                RaisePropertyChanged("DepositoSeleccionado");


            }
        }

        public Deposito NuevoDeposito
        {
            get { return _nuevoDeposito; }
            set
            {

                _nuevoDeposito = value;
                RaisePropertyChanged("NuevoDeposito");


            }
        }
        public bool FiltroChkBarco
        {
            get { return _filtroChkBarco; }
            set
            {

                _filtroChkBarco = value;
                RaisePropertyChanged("FiltroChkBarco");


            }
        }

        public bool EstaCargando
        {
            get { return _estaCargando; }
            set
            {

                _estaCargando = value;
                RaisePropertyChanged("EstaCargando");


            }
        }

        public bool FiltroChkProducto
        {
            get { return _filtroChkProducto; }
            set
            {

                _filtroChkProducto = value;
                RaisePropertyChanged("FiltroChkProducto");


            }
        }

        public bool FiltroChkFchIni
        {
            get { return _filtroChkFchIni; }
            set
            {

                _filtroChkFchIni = value;
                RaisePropertyChanged("FiltroChkFchIni");


            }
        }

        public bool FiltroChkFchFin
        {
            get { return _filtroChkFchFin; }
            set
            {

                _filtroChkFchFin = value;
                RaisePropertyChanged("FiltroChkFchFin");


            }
        }


        public DateTime FechaAhora
        {
            get { return _fechaAhora; }
            set
            {
                _fechaAhora = value;
                RaisePropertyChanged("FechaAhora");


            }
        }

        public DateTime FiltroFechaIni
        {
            get { return _filtroFechaIni; }
            set
            {
                _filtroFechaIni = value;
                RaisePropertyChanged("FiltroFechaIni");


            }
        }

        public DateTime FiltroFechaFin
        {
            get { return _filtroFechaFin; }
            set
            {
                _filtroFechaFin = value;
                RaisePropertyChanged("FiltroFechaFin");


            }
        }

        public string FiltroBarco
        {
            get { return _filtroBarco; }
            set
            {
                _filtroBarco = value;
                RaisePropertyChanged("FiltroBarco");


            }
        }


        public string FiltroProducto
        {
            get { return _filtroProducto; }
            set
            {
                _filtroProducto = value;
                RaisePropertyChanged("FiltroProducto");


            }
        }

        #endregion

        #region Entidades

        public EntitySet<Remito_Barco> Remitos
        {
            get { return _remitos; }
            set
            {

                _remitos = value;
           
         
                RaisePropertyChanged("Remitos");


            }
        }

        public PagedCollectionView  RemitosPaginado
        {
            get { return _remitosPaginado; }
            set
            {

                _remitosPaginado = value;

                RaisePropertyChanged("RemitosPaginado");


            }
        }

        public EntitySet<Proveedor> Proveeedores
        {
            get { return _proveeedores; }
            set
            {

                _proveeedores = value;
                RaisePropertyChanged("Proveeedores");


            }
        }

        public EntitySet<Carga> Cargas
        {
            get { return _cargas; }
            set
            {

                _cargas = value;
                RaisePropertyChanged("Cargas");


            }
        }

        public EntitySet<Deposito> Depositos
        {
            get { return _depositos; }
            set
            {

                _depositos = value;
                RaisePropertyChanged("Depositos");


            }
        }

        
        #endregion


        public DepositosViewModel()
        {
           if (IsInDesignMode)
            {
            ////    // Code runs in Blend --> create design time data.
            }
           else
            {
                Messenger.Default.Register<EnvioMensaje>(this, msg => procesarMensaje(msg));
                contexto = new SGTDomainContext();
                BotonGuardarDeposito = new RelayCommand(guardarDeposito);
                BotonNuevoDeposito = new RelayCommand(nuevoDepositoVentana);
                BotonBuscarDeposito = new RelayCommand(cargarDepositos);
                BotonModificarDeposito = new RelayCommand(modificarDeposito);
                BotonBuscarCarga = new RelayCommand(buscarCarga);
                BotonNavegarRemito = new RelayCommand(navegarRemito);
                BotonCargarRemitosCarga = new RelayCommand(cargarRemitos);
                BotonNuevoRemito = new RelayCommand(ingresarNuevoRemito);
                BotonGuardarRemitoCarga = new RelayCommand(guardarRemitoCarga);
                BotonModificarRemito = new RelayCommand(modificarRemito);
                BotonImprimirRemito = new RelayCommand(imprimirRemito);
                BotonEliminarRemito = new RelayCommand(eliminarRemito);

                EstaCargando = false;
        
                //ContenidoPagina = new Uri("/Views/Depositos.xaml", UriKind.Relative);

                //cargarDepositos();
           
            }
        }


        private void eliminarRemito()
        {
            if (RemitoSeleccionado != null)
            {

                int idRemito = (int)RemitoSeleccionado.Numero_Remito_Carga;

                MessageBoxResult s = MessageBox.Show("Se eliminará el remito " + idRemito + ". ¿Esta seguro?", "Cuidado", MessageBoxButton.OKCancel);
                if (s == MessageBoxResult.OK)
                {
                    contexto.Remito_Barcos.Remove(RemitoSeleccionado);

                    contexto.SubmitChanges(LoadOperation =>
                    {

                        if (LoadOperation.HasError)
                        {
                            //if (LoadOperation.Error.Message.Contains("DELETE"))
                            //{
                            Mensaje v = new Mensaje("Ocurrió un error en la operación.");
                            v.Show();
                            //}
                            cargarRemitos();
                            LoadOperation.MarkErrorAsHandled();
                        }
                        else
                        {
                            Mensaje v = new Mensaje("Remito eliminado.");
                            v.Show();
                        }

                    }, null);
                }

            }
        }

        private void procesarMensaje(EnvioMensaje msg)
        {
            //recalcularPesos();
        }
        private void nuevoDepositoVentana()
        {
            NuevoDeposito = new Deposito();
            NuevoDepositoWindow v = new NuevoDepositoWindow();
            v.Show();
        }

        private void cargarDepositos()
        {
            if (Depositos != null)
                Depositos.Clear();
            contexto.Load<Deposito>(contexto.GetDepositoQuery(), LoadOperation =>
                {
                    Depositos = contexto.Depositos;
                },null);
            
        }

        private void guardarDeposito()
        {
            try
            {
                if (NuevoDeposito.DepositoID == 0)
                    contexto.Depositos.Add(NuevoDeposito);
                contexto.SubmitChanges(LoadOperation =>
                    {
                        Mensaje v = new Mensaje("El Deposito " + NuevoDeposito.Nombre + " fue creado con éxito.");
                        v.Show();
                    }, null);
                
            }
            catch (Exception ex)
            {
                Mensaje v = new Mensaje(ex.Message);
                v.Show();
            }


        }

        private void buscarCarga()
        {
            EstaCargando = true;
            contexto.Load<Barco>(contexto.GetBarcoQuery(),LoadBehavior.RefreshCurrent,false);
            contexto.Load<Mercaderia>(contexto.GetMercaderiaQuery(),LoadBehavior.RefreshCurrent,false);
            contexto.Load<Proveedor>(contexto.GetProveedorQuery(),LoadBehavior.RefreshCurrent,false);
            cargarDepositos();
            if (Cargas != null)
                Cargas.Clear();
            string nomBarco = null;
            string prod = null;
            DateTime ini = new DateTime(1900, 1, 1);
            DateTime fin = new DateTime(2100, 1, 1);

            if (FiltroChkBarco == true)
                nomBarco = FiltroBarco;
            if (FiltroChkProducto == true)
                prod = FiltroProducto.ToUpper();
            if (FiltroChkFchIni == true)
                ini = FiltroFechaIni;
            if (FiltroChkFchFin == true)
                fin = FiltroFechaFin;
            contexto.Load<Carga>(contexto.GetCargaFiltradaQuery(nomBarco, prod, ini, fin), LoadOperation =>
                {
                    Cargas = contexto.Cargas;
                    EstaCargando = false;
                },null);
           
            
        }

        private void navegarRemito()
        {
            cargarRemitos();

            //EnvioMensaje msg = new EnvioMensaje("/Remitos");
            //Messenger.Default.Send<EnvioMensaje, NavegacionViewModel>(msg);
            //ContenidoPagina = new Uri("/Views/Remitos.xaml", UriKind.Relative);
          
        }

        private void cargarRemitos()
        {
            EstaCargando = true;
          
            if (CargaSeleccionada != null)
            {
                 int id = CargaSeleccionada.Id;
                 if (Remitos != null)
                     Remitos.Clear();
                 contexto.Load<Bodega>(contexto.GetBodegaByCargaQuery(id), LoadOperation =>
                   {
                       cargarRemitosInterno(id);
                   }, null);
               
            }
            else
            {
                Mensaje v = new Mensaje("Por favor seleccione una carga");
                v.Show();
            }
        }

        private void cargarRemitosInterno(int idCarga)
        {
            contexto.Load<Remito_Barco>(contexto.GetRemito_Barco_CargaQuery(idCarga), LoadOperation =>
            {
                Remitos = contexto.Remito_Barcos;
                recalcularPesos();
                EstaCargando = false;
                RemitosPaginado = new PagedCollectionView(Remitos);

            }, null);
        }


        private void modificarDeposito()
        {
            NuevoDeposito = DepositoSeleccionado;
            NuevoDepositoWindow v = new NuevoDepositoWindow();
            v.Show();
        }

        private void modificarRemito()
        {
            NuevoRemito = RemitoSeleccionado;
            contexto.Load<Proveedor>(contexto.GetProveedorQuery(), LoadOperation =>
            {
                Proveeedores = contexto.Proveedors;
                IngresoRemitosWindow v = new IngresoRemitosWindow("Modificar Remito");
                v.Show();
            }, null);
            
        }

        private void ingresarNuevoRemito()
        {
            contexto.Load<Proveedor>(contexto.GetProveedorQuery(), LoadOperation =>
                {
                    Proveeedores = contexto.Proveedors;
                    /*NuevoRemito = new Remito_Barco();
                    NuevoRemito.Carga = CargaSeleccionada;
                    NuevoRemito.setNumeroID();*/
                    NuevoRemito = new Remito_Barco(CargaSeleccionada);
                    IngresoRemitosWindow v = new IngresoRemitosWindow("Nuevo Remito");
                    v.Show();
                }, null);
         
          
        }

        private void guardarRemitoCarga()
        {
            try
            {
                NuevoRemito.validarRemito(); //Solo se exige que tenga bodega
                
                if (NuevoRemito.Id == 0)
                {
                    //NuevoRemito.Carga = CargaSeleccionada;
                    //NuevoRemito.setNumeroID();
                    contexto.Remito_Barcos.Add(NuevoRemito);
                }
                contexto.SubmitChanges(LoadOperation =>
                    {
                       
                        Mensaje v = new Mensaje("Remito " + NuevoRemito.Numero_Remito + " cargado con éxito.");
                        v.Show();
                        NuevoRemito = new Remito_Barco(CargaSeleccionada);
                        cargarRemitos();
                      
                        recalcularPesos();
                    },null);
               
            }
            catch (Exception ex)
            {
                Mensaje v = new Mensaje(ex.Message);
                v.Show();
            }
        }


        

        private void recalcularPesos()
        {
            PesoNeto = 0;
            PesoANP = 0;
            decimal PesoTara = 0;
            foreach (Remito_Barco r in Remitos)
            {
                if (r.Peso_ANP != null && r.PesoNeto != null && r.Tara != null)
                {
                    PesoNeto += (decimal)r.Bruto1 + (decimal)r.Bruto2;
                    PesoANP += (decimal)r.Peso_ANP;
                    PesoTara += (decimal)r.Tara_1 + (decimal)r.Tara_2;
                }
            }
            PesoNeto = PesoNeto - PesoTara;
        }

        private void imprimirRemito()
        {
            Plantilla3Vias plantilla = new Plantilla3Vias();
            PrintDocument pd = new PrintDocument();
            FechaAhora = DateTime.Now;
            // Set the printable area

            Canvas c = new Canvas();
            c.Width = 797.8;
            c.Height = 1123.2;
            ScaleTransform scaleTransform = new ScaleTransform();
            scaleTransform.ScaleX = 0.9;
            scaleTransform.ScaleY = 0.9;
            plantilla.RenderTransform = scaleTransform;


           
         
            pd.PrintPage += (s, args) =>
            {


                c.Children.Add(plantilla);
                args.PageVisual = c;
                args.HasMorePages = false;
                
            };
            
            pd.EndPrint += (s, args) =>
            {

              
            };

            // Print the document
            pd.Print("Remito");
        }



        ////public override void Cleanup()
        ////{
        ////    // Clean own resources if needed

        ////    base.Cleanup();
        ////}
    }
}